/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tools;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Mika
 */
public class MultiThreadMultiplier {

    public static final int MATRIX_NO = 16;
    int[][] product;
    public int phase = 0;

    public static void main(String[] args) {

        long startTime = System.currentTimeMillis();
        //--

        MatrixReader mr = new MatrixReader();
        mr.readAllMatrices(MATRIX_NO);
        //mr.readAllMatrices("./test", MATRIX_NO);
        ArrayList<int[][]> mList = mr.getMatrices();
        MultiThreadMultiplier mtm = new MultiThreadMultiplier();
        mtm.calculate(mList);
        int[][] result = mtm.getProduct();
        //System.out.println("Final product: " + result);
        //--
        long endTime = System.currentTimeMillis();
        System.out.println("Execution took: " + (endTime - startTime) + " ms");
        
        System.out.print("Print final matrix? ");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String answer = null;
        try {
            answer = br.readLine();
        } catch (IOException ioe) {
            System.out.println("IO error trying to read your answer");
            System.exit(-1);
        }
        if(answer.equalsIgnoreCase("yes") || answer.equalsIgnoreCase("y")) {
            Matrix.mprint(result);
        }
    }

    public int[][] getProduct() {
        return product;
    }

    public void calculate(ArrayList<int[][]> mList) {
        ArrayList<MatrixThread> pool = new ArrayList();
        MatrixThread st = null;
        int[][] product;
        if (mList.size() == 2) {
            System.out.println("Final phase!");
            int[][] m1 = mList.remove(0);
            int[][] m2 = mList.remove(0);
            this.product = Matrix.multiply(m1, m2);
        } else {
            this.phase++;
            System.out.println("Starting phase " + this.phase);
            int count = mList.size();
            for (int i = 0; i < count; i += 2) {
                int[][] m1 = mList.remove(0);
                int[][] m2 = mList.remove(0);
                st = new MatrixThread(m1, m2, "single-thread" + i);
                pool.add(st);
            }
            mList.clear();
            for (MatrixThread mt : pool) {
                Thread ttt = mt.getThread();
                try {
                    ttt.join();
                } catch (InterruptedException ex) {
                    Logger.getLogger(MultiThreadMultiplier.class.getName()).log(Level.SEVERE, null, ex);
                }

            }
            for (MatrixThread mt : pool) {
                mList.add(mt.getProduct());
            }


            calculate(mList);
        }
    }
}
